package com.abhimanyu.dataaccess;

import java.util.ArrayList;
import java.util.List;

import com.abhimanyu.dataaccess.model.User;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;

/**
 * @author Abhimanyu
 * 
 */
public class MongoDbUsersDao extends AbstractUsersDao {

	private MongoClient client;
	
	public MongoDbUsersDao() {
		try {
			client = new MongoClient();
		} catch (Exception e) {
			throw new RuntimeException("Error While Creating MONGO DB");
		}
	}

	/*
	 * public List<User> fetchAllUsers() { DBCollection userTable =
	 * getUserTable(); DBObject query =
	 * QueryBuilder.start(enabledColumnName).is(true).get();
	 * 
	 * DBCursor tableData = userTable.find(query, new
	 * BasicDBObject(mobileNumberColumnName, true).append("_id", false));
	 * DBObject tableRow = null; List<User> listOfUsers = new
	 * ArrayList<User>(10); User user = null; Object object = null; while
	 * (tableData.hasNext()) { user = new User(); tableRow = tableData.next();
	 * 
	 * object = tableRow.get(mobileNumberColumnName);
	 * user.setMobileNumber(getObjectAsString(object));
	 * 
	 * listOfUsers.add(user); } return listOfUsers; }
	 */
	public List<User> fetchAll() {
		DBCollection userTable = getUserTable();
		DBObject query = new BasicDBObject();
		query.put(getEnabledColumnName(), true);

		DBCursor tableData = userTable.find(query);
		DBObject tableRow = null;
		List<User> listOfUsers = new ArrayList<User>(10);
		User user = null;
		Object object = null;
		while (tableData.hasNext()) {
			user = new User();
			tableRow = tableData.next();

			object = tableRow.get(getEmailAddressColumnName());
			user.setEmail(getObjectAsString(object));

			object = tableRow.get(getUserNameColumnName());
			user.setUserName(getObjectAsString(object));

			object = tableRow.get(getMobileNumberColumnName());
			user.setMobileNumber(getObjectAsString(object));

			object = tableRow.get(getEnabledColumnName());
			user.setEnabled(Boolean.valueOf(getObjectAsString(object)));

			object = tableRow.get(getScheduledAtColumnName());
			user.setScheduledAt(getObjectAsString(object));

			listOfUsers.add(user);
		}
		destroy();
		return listOfUsers;
	}

	public void save(User user) {
		DBCollection tableData = getUserTable();
		DBObject object = new BasicDBObject();
		object.put(getEmailAddressColumnName(), user.getEmail());
		object.put(getUserNameColumnName(), user.getUserName());
		object.put(getMobileNumberColumnName(), user.getMobileNumber());
		object.put(getEnabledColumnName(), user.isEnabled());
		tableData.insert(object);
	}

	public void update(User user) {
		DBCollection tableData = getUserTable();
		BasicDBObject object = new BasicDBObject();

		BasicDBObject updateQuery = new BasicDBObject();
		if (user.getEmail() != null) {
			updateQuery.append(getEmailAddressColumnName(), user.getEmail());
		}
		if (user.getMobileNumber() != null) {
			updateQuery.append(getMobileNumberColumnName(), user.getMobileNumber());
		}

		if (user.isEnabled() != null) {
			updateQuery.append(getEnabledColumnName(), user.isEnabled());
		}

		object.append("$set", updateQuery);

		BasicDBObject whereClause = new BasicDBObject();
		whereClause.append(getUserNameColumnName(), user.getUserName());
		tableData.update(whereClause, object);
	}

	private DBCollection getUserTable() {
		DB database = client.getDB(getDatabaseName());
		DBCollection userTable = database.getCollection(getTableName());
		return userTable;
	}

	private String getObjectAsString(Object object) {
		return (object != null ? object.toString() : null);
	}

	public void destroy() {
		System.out.println("Closing DB Connection");
		client.close();
	}

	public void setClient(MongoClient client) {
		this.client = client;
	}

	
	public MongoClient getClient() {
		return client;
	}
	
}
